﻿using System;
using System.Collections.Specialized;
using App_Code.Helpers;
using Rss;
using System.Text;
using System.Collections.Generic;

namespace App_Code.SiteParsers
{
    /// <summary>
    /// Summary description for BasePluginParser
    /// </summary>
    public abstract class BasePluginParser : IPluginParser
    {
        #region Protected Members
        private readonly CacheManager _cacheManager = CacheManager.Instance;
        protected string _defaultUrl = string.Empty;
        protected NameValueCollection _queryStringParams;
        protected int _pluginId;
        protected PluginMode _pluginMode;

        protected enum PluginMode
        {
            IDLE_MODE,
            CATEGORIES_MODE,
            SEARCH_MODE,
            NEXT_PAGE_MODE,
            MOVIES_MODE,
            MOVIE_MODE
        } 
        #endregion

        #region Public Properties
        public string Name { get; set; }
        public string Description { get; set; }
        public string Url { get; set; }
        public string SearchText { get; set; }

        #endregion

        #region Implementation of IPluginParser
        public virtual RssFeed Run(NameValueCollection queryStringParams)
        {            
            throw new NotImplementedException();
        }

        public virtual void RunUntillPage(int pageNumber)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region Protected Methods
        protected virtual void InitMembers(NameValueCollection queryStringParams)
        {
            this._queryStringParams = queryStringParams;
            //this._request.ContentEncoding = System.Text.Encoding.UTF8;
            this._pluginId = Utils.GetParam(this._queryStringParams, "pluginId", -1);
            var pluginLink = Utils.GetParam(this._queryStringParams, "pluginLink", _defaultUrl);
            this.Url = pluginLink.Equals(_defaultUrl) ? _defaultUrl : Utils.DecodeUrl(pluginLink);
            this._pluginMode = (PluginMode)Utils.GetParam(this._queryStringParams, Common.PLUGIN_MODE, (int)PluginMode.IDLE_MODE);
            if(_pluginMode == PluginMode.SEARCH_MODE)
            {
                this.SearchText = pluginLink;
                this.Url = _defaultUrl;
            }
        }

        protected RssFeed CreateErrorResponse(string errorMessage)
        {
            var channel = new RssChannel
            {
                Title = this.Name,
                Description = "Error Message",
                Language = "he"
            };
            channel.LastBuildDate = channel.Items.LatestPubDate();

            var item = new RssItem
            {
                Title = "Error",
                Description = errorMessage,
                PubDate = DateTime.Now,
                Comments = "Error"
            };

            channel.Items.Add(item);

            var feed = new RssFeed { Encoding = Encoding.UTF8 };
            feed.Channels.Add(channel);
            return feed;
        }

        protected void AddToCache(string key, RssFeed rssFeed)
        {
            if (_cacheManager.IsInCache(key)) return;

            _cacheManager.CacheData(key, rssFeed, DateTime.UtcNow.AddMinutes(60));
        }

        protected RssFeed LoadFromCache(string key)
        {
            if (_cacheManager.IsInCache(key))
            {
                var rssFeed = _cacheManager.GetData(key) as RssFeed;
                if (rssFeed != null)
                {
                    return rssFeed;
                }
            }            
            return null;
        }

        protected RssFeed LoadMovie()
        {
            try
            {
                VideoResult videoResult = null;
                var rssCategory = new RssCategory { Name = "Movie" };

                if (VideoBBExtractor.IsContainVideoLink(this.Url))
                {
                    videoResult = VideoBBExtractor.ExtractMovieUrl(this.Url);
                }

                else if (VideozerExtractor.IsContainVideoLink(this.Url))
                {
                    videoResult = VideozerExtractor.ExtractMovieUrl(this.Url);
                }

                else if (MytubeExtractor.IsContainVideoLink(this.Url))
                {
                    videoResult = MytubeExtractor.ExtractMovieUrl(this.Url);
                }

                else if (SdarotOrgExtractor.IsContainVideoLink(this.Url))
                {
                    videoResult = SdarotOrgExtractor.ExtractMovieUrl(this.Url);
                }

                else if (MultiUploadExtractor.IsContainVideoLink(this.Url))
                {
                    videoResult = MultiUploadExtractor.ExtractMovieUrl(this.Url);
                }

                else if (MegaVideoExtractor.IsContainVideoLink(this.Url))
                {
                    videoResult = MegaVideoExtractor.ExtractMovieUrl(this.Url);
                    if (!videoResult.IsValid)
                    {
                        rssCategory = new RssCategory { Name = "MegaVideo" };
                        videoResult.IsValid = true;
                    }
                }

                else if (CuevanaTVExtractor.IsContainVideoLink(this.Url))
                {
                    videoResult = CuevanaTVExtractor.ExtractMovieUrl(this.Url);
                }

                if (videoResult == null || !videoResult.IsValid)
                {
                    throw new Exception(string.Format("Unknown video link: {0}", this.Url));
                }

                var rssChannel = new RssChannel
                {
                    Title = "Movies Channel",
                    Description = "Movies List",
                    Link = new Uri(string.Format("{0}?pluginId={1}", Utils.GetSiteUrl(), this._pluginId)),
                    Language = "he"
                };

                var rssItem = new RssItem
                {
                    Title = videoResult.MovieName,
                    Description = (videoResult.VideoDetails != null) ? videoResult.VideoDetails.Description : string.Empty,
                    PubDate = DateTime.Now,
                    Link = new Uri(Utils.LoopDecodeUrl(videoResult.Link))
                };


                rssItem.Categories.Add(rssCategory);
                rssChannel.Items.Add(rssItem);

                var feed = new RssFeed { Encoding = Encoding.UTF8 };
                feed.Channels.Add(rssChannel);

                return feed;
            }
            catch (Exception ex)
            {
                return CreateErrorResponse(ex.Message);
            }
        }

        protected virtual List<string> GetMovieLinks(string pageContent)
        {
            var movieLinks = new List<string>();
            if (VideoBBExtractor.IsContainVideoLink(pageContent))
            {
                movieLinks.AddRange(VideoBBExtractor.GetMovieUrls(pageContent));
            }

            if (MytubeExtractor.IsContainVideoLink(pageContent))
            {
                movieLinks.AddRange(MytubeExtractor.GetMovieUrls(pageContent));
            }

            if (VideozerExtractor.IsContainVideoLink(pageContent))
            {
                movieLinks.AddRange(VideozerExtractor.GetMovieUrls(pageContent));
            }

            if (MegaVideoExtractor.IsContainVideoLink(pageContent))
            {
                movieLinks.AddRange(MegaVideoExtractor.GetMovieUrls(pageContent));
            }

            if (TopdownMeExtractor.IsContainVideoLink(pageContent))
            {
                movieLinks.AddRange(TopdownMeExtractor.GetMovieUrls(pageContent));
            }

            //if (MegaVideoExtractor.IsContainMegaUploadVideoLink(pageContent))
            //{
            //    var videoLink = MegaVideoExtractor.ConvertToMegaVideoLink(pageContent);
            //    return MegaVideoExtractor.GetMovieUrls(videoLink);
            //}
            return movieLinks;
        }

        protected void AddSearchLink(RssChannel rssChannel, string searchUrl)
        {
            var movie = new Movie
            {
                Name = "Search",
            };

            movie.MovieLinks.Add(searchUrl);

            var movieItems = movie.GetRssItems(Utils.GetSiteUrl(), this._pluginId, (int)PluginMode.SEARCH_MODE);
            foreach (var movieItem in movieItems)
            {
                rssChannel.Items.Add(movieItem);
            }
        }
        #endregion
    }
}